﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.ComponentModel;

namespace EasyEntities.RIA.Controls
{
    /// <summary>
    /// 对象验证控件
    /// </summary>
    public class ValidationControl : Control
    {
        static ValidationControl()
        {
            DefaultStyleKeyProperty.OverrideMetadata(typeof(ValidationControl), new FrameworkPropertyMetadata(typeof(ValidationControl)));
        }

        public ValidationControl()
        {
            base.Loaded += new RoutedEventHandler(ValidationControl_Loaded);
        }


        void ValidationControl_Loaded(object sender, RoutedEventArgs e)
        {
            bool v = Validate();
            if (v)
            {
                this.Visibility = Visibility.Collapsed;
            }
            else
            {
                this.Visibility = Visibility.Visible;
            }
        }

        /// <summary>
        /// 验证函数
        /// </summary>
        /// <returns></returns>
        private bool Validate()
        {
            if (DesignerProperties.GetIsInDesignMode(this))
            {
                return false;
            }
            Binding propertyBinding = BindingOperations.GetBinding(this, SourceProperty);
            if (propertyBinding == null || DataContext == null)
                // Binding must be used
                return true;

            string propertyPath = string.Empty;
            var memberPath = propertyBinding.Path.Path;
            string[] paths = memberPath.Split('.');
            IDataErrorInfo errorInfo = null;
            if (paths.Length == 1)
            {
                propertyPath = memberPath;
                errorInfo = DataContext as IDataErrorInfo;
            }
            else // ==2的情况
            {

                propertyPath = paths[1];
                var objPath = paths[0];
                var propertyInfo = DataContext.GetType().GetProperty(objPath);
                if (propertyInfo != null)
                    errorInfo = propertyInfo.GetValue(DataContext, null) as IDataErrorInfo;

            }
            //2层对象内，找不到错误接口
            if (errorInfo == null)
                return true;

            //验证
            string errorMessage = errorInfo[propertyPath];

            if (!string.IsNullOrEmpty(errorMessage))
            {
                ErrorMessage = errorMessage;
                return false;
            }

            return true;
        }


        /// <summary>
        /// 错误提示信息
        /// </summary>
        public string ErrorMessage
        {
            set
            {
                SetValue(ErrorMessageProperty, value);
            }
            get
            {
                return (string)GetValue(ErrorMessageProperty);
            }
        }
        public static DependencyProperty ErrorMessageProperty = DependencyProperty.Register("ErrorMessage", typeof(string), typeof(ValidationControl));



        /// <summary>
        /// 触发源
        /// </summary>
        public object Source
        {
            set
            {
                SetValue(SourceProperty, value);
            }
            get
            {
                return GetValue(SourceProperty);
            }
        }
        public static DependencyProperty SourceProperty = DependencyProperty.Register("Source", typeof(object), typeof(ValidationControl), new PropertyMetadata(new PropertyChangedCallback(OnSourcePropertyChanged)));


        public static void OnSourcePropertyChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
        {
            var vc = sender as ValidationControl;
            if (vc != null)
            {
                bool v = vc.Validate();
                if (v)
                {
                    vc.Visibility = Visibility.Collapsed;
                }
                else
                {
                    vc.Visibility = Visibility.Visible;
                }
            }

        }

    }
}
